package com.cinema.servlet.admin;

import com.cinema.dao.MovieDAO;
import com.cinema.dao.CinemaDAO;
import com.cinema.dao.HallDAO;
import com.cinema.entity.Movie;
import com.cinema.entity.Cinema;
import com.cinema.entity.Hall;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 管理员电影管理Servlet
 */
@MultipartConfig(
    fileSizeThreshold = 1024 * 1024 * 2, // 2MB
    maxFileSize = 1024 * 1024 * 10,      // 10MB
    maxRequestSize = 1024 * 1024 * 50    // 50MB
)
public class AdminMovieServlet extends HttpServlet {
    private MovieDAO movieDAO = new MovieDAO();
    private CinemaDAO cinemaDAO = new CinemaDAO();
    private HallDAO hallDAO = new HallDAO();

    private static final String PROJECT_ROOT = "D:\\project\\java\\cinema-booking-system\\src\\main\\webapp";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String action = request.getParameter("action");

        if ("add".equals(action)) {
            showAddMovieForm(request, response);
        } else if ("edit".equals(action)) {
            showEditMovieForm(request, response);
        } else {
            showMovieList(request, response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String action = request.getParameter("action");

        if ("add".equals(action)) {
            handleAddMovie(request, response);
        } else if ("edit".equals(action)) {
            handleEditMovie(request, response);
        } else if ("updateStatus".equals(action)) {
            handleUpdateStatus(request, response);
        } else {
            doGet(request, response);
        }
    }

    /**
     * 显示电影列表
     */
    private void showMovieList(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            List<Movie> movies = movieDAO.findAll();
            request.setAttribute("movies", movies);

            // 检查是否有消息
            String message = request.getParameter("message");
            if (message != null && !message.trim().isEmpty()) {
                request.setAttribute("message", message);
            }

            request.getRequestDispatcher("/admin/movies.jsp").forward(request, response);

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取电影列表失败");
            request.getRequestDispatcher("/error/500.jsp").forward(request, response);
        }
    }

    /**
     * 显示添加电影表单
     */
    private void showAddMovieForm(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            // 获取影院和影厅数据
            List<Cinema> cinemas = cinemaDAO.findAll();
            List<Hall> halls = hallDAO.findAll();

            request.setAttribute("cinemas", cinemas);
            request.setAttribute("halls", halls);
            request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取影院信息失败");
            request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);
        }
    }

    /**
     * 显示编辑电影表单
     */
    private void showEditMovieForm(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String movieIdStr = request.getParameter("id");

        if (movieIdStr == null || movieIdStr.trim().isEmpty()) {
            response.sendRedirect(request.getContextPath() + "/admin/movies");
            return;
        }

        try {
            Integer movieId = Integer.parseInt(movieIdStr);
            Movie movie = movieDAO.findById(movieId);

            if (movie == null) {
                request.setAttribute("error", "电影不存在");
                request.getRequestDispatcher("/error/404.jsp").forward(request, response);
                return;
            }

            // 获取影院和影厅数据
            List<Cinema> cinemas = cinemaDAO.findAll();
            List<Hall> halls = hallDAO.findAll();

            request.setAttribute("movie", movie);
            request.setAttribute("cinemas", cinemas);
            request.setAttribute("halls", halls);
            request.setAttribute("isEdit", true);
            request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);

        } catch (NumberFormatException e) {
            try {
                String message = URLEncoder.encode("电影ID格式错误", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/admin/movies?error=" + message);
            } catch (Exception ex) {
                response.sendRedirect(request.getContextPath() + "/admin/movies");
            }
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "获取电影信息失败");
            request.getRequestDispatcher("/error/500.jsp").forward(request, response);
        }
    }

    /**
     * 处理添加电影
     */
    private void handleAddMovie(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            Movie movie = createMovieFromRequest(request);

            boolean success = movieDAO.addMovie(movie);

            if (success) {
                try {
                    String message = URLEncoder.encode("电影添加成功", "UTF-8");
                    response.sendRedirect(request.getContextPath() + "/admin/movies?message=" + message);
                } catch (Exception ex) {
                    response.sendRedirect(request.getContextPath() + "/admin/movies");
                }
            } else {
                request.setAttribute("error", "添加电影失败");
                request.setAttribute("movie", movie);
                // 重新加载影院和影厅数据
                try {
                    List<Cinema> cinemas = cinemaDAO.findAll();
                    List<Hall> halls = hallDAO.findAll();
                    request.setAttribute("cinemas", cinemas);
                    request.setAttribute("halls", halls);
                } catch (Exception ex) {
                    // 如果获取失败，使用空列表
                }
                request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "添加电影过程中发生错误：" + e.getMessage());
            // 重新加载影院和影厅数据
            try {
                List<Cinema> cinemas = cinemaDAO.findAll();
                List<Hall> halls = hallDAO.findAll();
                request.setAttribute("cinemas", cinemas);
                request.setAttribute("halls", halls);
            } catch (Exception ex) {
                // 如果获取失败，使用空列表
            }
            request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);
        }
    }

    /**
     * 处理编辑电影
     */
    private void handleEditMovie(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String movieIdStr = request.getParameter("id");
        if (movieIdStr == null || movieIdStr.trim().isEmpty()) {
            try {
                String message = URLEncoder.encode("电影ID无效", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/admin/movies?error=" + message);
            } catch (Exception ex) {
                response.sendRedirect(request.getContextPath() + "/admin/movies");
            }
            return;
        }

        try {
            Movie movie = createMovieFromRequest(request);
            movie.setId(Integer.parseInt(movieIdStr));

            boolean success = movieDAO.updateMovie(movie);

            if (success) {
                try {
                    String message = URLEncoder.encode("电影更新成功", "UTF-8");
                    response.sendRedirect(request.getContextPath() + "/admin/movies?message=" + message);
                } catch (Exception ex) {
                    response.sendRedirect(request.getContextPath() + "/admin/movies");
                }
            } else {
                request.setAttribute("error", "更新电影失败");
                request.setAttribute("movie", movie);
                request.setAttribute("isEdit", true);
                // 重新加载影院和影厅数据
                try {
                    List<Cinema> cinemas = cinemaDAO.findAll();
                    List<Hall> halls = hallDAO.findAll();
                    request.setAttribute("cinemas", cinemas);
                    request.setAttribute("halls", halls);
                } catch (Exception ex) {
                    // 如果获取失败，使用空列表
                }
                request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("error", "更新电影过程中发生错误：" + e.getMessage());

            // 重新获取电影信息用于表单回显
            try {
                Integer movieId = Integer.parseInt(movieIdStr);
                Movie movie = movieDAO.findById(movieId);
                request.setAttribute("movie", movie);
                request.setAttribute("isEdit", true);
            } catch (Exception ex) {
                // 如果获取失败，直接跳转回列表
                try {
                    String message = URLEncoder.encode("更新失败", "UTF-8");
                    response.sendRedirect(request.getContextPath() + "/admin/movies?error=" + message);
                } catch (Exception urlEx) {
                    response.sendRedirect(request.getContextPath() + "/admin/movies");
                }
                return;
            }

            request.getRequestDispatcher("/admin/movie-form.jsp").forward(request, response);
        }
    }

    /**
     * 处理更新电影状态
     */
    private void handleUpdateStatus(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String movieIdStr = request.getParameter("movieId");
        String status = request.getParameter("status");

        try {
            Integer movieId = Integer.parseInt(movieIdStr);

            boolean success = movieDAO.updateMovieStatus(movieId, status);

            if (success) {
                try {
                    String message = URLEncoder.encode("电影状态更新成功", "UTF-8");
                    response.sendRedirect(request.getContextPath() + "/admin/movies?message=" + message);
                } catch (Exception ex) {
                    response.sendRedirect(request.getContextPath() + "/admin/movies");
                }
            } else {
                try {
                    String message = URLEncoder.encode("更新失败", "UTF-8");
                    response.sendRedirect(request.getContextPath() + "/admin/movies?error=" + message);
                } catch (Exception ex) {
                    response.sendRedirect(request.getContextPath() + "/admin/movies");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            try {
                String message = URLEncoder.encode("更新过程中发生错误", "UTF-8");
                response.sendRedirect(request.getContextPath() + "/admin/movies?error=" + message);
            } catch (Exception ex) {
                response.sendRedirect(request.getContextPath() + "/admin/movies");
            }
        }
    }

    /**
     * 从请求中创建Movie对象
     */
    private Movie createMovieFromRequest(HttpServletRequest request) throws Exception {
        Movie movie = new Movie();

        movie.setTitle(request.getParameter("title"));
        movie.setEnglishTitle(request.getParameter("englishTitle"));
        movie.setDirector(request.getParameter("director"));
        movie.setActors(request.getParameter("actors"));
        movie.setGenre(request.getParameter("genre"));

        String durationStr = request.getParameter("duration");
        if (durationStr != null && !durationStr.trim().isEmpty()) {
            movie.setDuration(Integer.parseInt(durationStr));
        }

        movie.setRating(request.getParameter("rating"));

        String releaseDateStr = request.getParameter("releaseDate");
        if (releaseDateStr != null && !releaseDateStr.trim().isEmpty()) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            movie.setReleaseDate(sdf.parse(releaseDateStr));
        }

        // 处理海报图片上传
        String posterUrl = handlePosterUpload(request);
        if (posterUrl != null && !posterUrl.trim().isEmpty()) {
            movie.setPosterUrl(posterUrl);
        } else {
            // 如果没有上传文件，使用URL字段
            movie.setPosterUrl(request.getParameter("posterUrl"));
        }

        movie.setTrailerUrl(request.getParameter("trailerUrl"));
        movie.setSynopsis(request.getParameter("synopsis"));
        movie.setLanguage(request.getParameter("language"));
        movie.setCountry(request.getParameter("country"));
        movie.setStatus(request.getParameter("status"));

        return movie;
    }

    /**
     * 处理海报图片上传
     */
    private String handlePosterUpload(HttpServletRequest request) throws Exception {
        Part filePart = request.getPart("posterFile");

        if (filePart == null || filePart.getSize() == 0) {
            return null;
        }

        String fileName = getFileName(filePart);
        if (fileName == null || fileName.trim().isEmpty()) {
            return null;
        }

        // 验证文件类型
        String contentType = filePart.getContentType();
        if (!isValidImageType(contentType)) {
            throw new Exception("只支持JPG、PNG、GIF格式的图片");
        }

        // 生成唯一文件名
        String fileExtension = getFileExtension(fileName);
        String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

        // 获取两个上传目录的绝对路径
        // 1. 项目源码目录
        String sourceUploadPath = PROJECT_ROOT + File.separator + "images" + File.separator + "movies";
        File sourceUploadDir = new File(sourceUploadPath);

        // 2. Tomcat运行目录
        String runtimeUploadPath = getServletContext().getRealPath("") + File.separator + "images" + File.separator + "movies";
        File runtimeUploadDir = new File(runtimeUploadPath);

        System.out.println("电影海报源码目录: " + sourceUploadPath);
        System.out.println("电影海报运行目录: " + runtimeUploadPath);

        // 如果目录不存在，创建目录
        if (!sourceUploadDir.exists()) {
            boolean created = sourceUploadDir.mkdirs();
            if (!created) {
                System.err.println("创建源码上传目录失败: " + sourceUploadPath);
                throw new Exception("创建源码上传目录失败");
            }
        }

        if (!runtimeUploadDir.exists()) {
            boolean created = runtimeUploadDir.mkdirs();
            if (!created) {
                System.err.println("创建运行时上传目录失败: " + runtimeUploadPath);
                throw new Exception("创建运行时上传目录失败");
            }
        }

        // 保存到源码目录
        String sourceFilePath = sourceUploadPath + File.separator + uniqueFileName;
        filePart.write(sourceFilePath);
        System.out.println("图片已保存到源码目录: " + sourceFilePath);

        // 保存到运行时目录
        String runtimeFilePath = runtimeUploadPath + File.separator + uniqueFileName;
        try {
            // 复制文件到运行时目录
            java.nio.file.Files.copy(
                java.nio.file.Paths.get(sourceFilePath),
                java.nio.file.Paths.get(runtimeFilePath),
                java.nio.file.StandardCopyOption.REPLACE_EXISTING
            );
            System.out.println("图片已复制到运行时目录: " + runtimeFilePath);
        } catch (Exception copyEx) {
            System.err.println("复制图片到运行时目录失败: " + copyEx.getMessage());
            // 不抛出异常，因为源码目录已保存成功
        }

        // 返回包含contextPath的路径用于数据库存储
        return request.getContextPath()+"/images/movies/" + uniqueFileName;
    }

    /**
     * 获取文件名
     */
    private String getFileName(Part part) {
        String contentDisposition = part.getHeader("content-disposition");
        if (contentDisposition != null) {
            for (String content : contentDisposition.split(";")) {
                if (content.trim().startsWith("filename")) {
                    return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
                }
            }
        }
        return null;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            return fileName.substring(lastDotIndex);
        }
        return "";
    }

    /**
     * 验证是否为有效的图片类型
     */
    private boolean isValidImageType(String contentType) {
        return contentType != null && (
            contentType.equals("image/jpeg") ||
            contentType.equals("image/jpg") ||
            contentType.equals("image/png") ||
            contentType.equals("image/gif")
        );
    }
}
